﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KZ.Express.H.DAL;
using KZ.Express.H.ENT;
using KZ.Utilities;
using System.Data;
using System.Reflection;

namespace KZ.Express.H.BLL
{
    public interface IBaseBLL
    {
        object Insert(BaseENT entity);
        object Update(BaseENT entity);
        void Delete<T>(List<int> idList, int userID, bool isLog);
        Dictionary<string, object> ExecuteNonQuery(string query, SearchCriteria search, params string[] outParameters);
        T GetByID<T>(object entityID);
        T GetEntity<T>(SearchCriteria search);
        T GetEntity<T>(string query, SearchCriteria search);
        DataTable GetDataTable<T>(SearchCriteria search);
        DataTable GetDataTable(string query, SearchCriteria search);
    }

    public class BaseBLL : IBaseBLL
    {
        protected BaseDAL _dal;

        public BaseBLL()
        {
            _dal = new BaseDAL();
        }

        public virtual object Insert(BaseENT entity)
        {
            try
            {
                _dal.BeginTransaction();

                entity.ValidateData();
                int id = Utility.IntParse(_dal.Insert(entity));

                if (id == -1)
                    throw new BusinessLogicException("Mã " + entity.Name + " đã tồn tại, bạn vui lòng nhập mã " + entity.Name + " khác");
                else if (id == -2)
                {
                    entity.IsRecovery = 1;
                    throw new BusinessLogicException("Dữ liệu có mã " + entity.Name + "này đã bị xóa, bạn có muốn khôi phục lại?");
                }

                _dal.CommitTransaction();
                return id;
            }
            catch (DataAccessException ex)
            {
                _dal.RollbackTransaction();
                throw new BusinessLogicException(ex.Message);
            }
        }

        public virtual object Update(BaseENT entity)
        {
            try
            {
                _dal.BeginTransaction();

                entity.ValidateData();
                int id = Utility.IntParse(_dal.Update(entity));

                if (id == -1)
                    throw new BusinessLogicException("Mã " + entity.Name + " đã tồn tại, bạn vui lòng nhập mã " + entity.Name + " khác");

                _dal.CommitTransaction();
                return id;
            }
            catch (DataAccessException ex)
            {
                _dal.RollbackTransaction();
                throw new BusinessLogicException(ex.Message);
            }
        }

        public void Delete<T>(List<int> idList, int userID, bool isLog)
        {
            try
            {
                _dal.BeginTransaction();

                foreach (int id in idList)
                    _dal.Delete<T>(id, userID, isLog);

                _dal.CommitTransaction();
            }
            catch (DataAccessException ex)
            {
                _dal.RollbackTransaction();
                throw new BusinessLogicException(ex.Message);
            }
        }

        public Dictionary<string, object> ExecuteNonQuery(string query, SearchCriteria search, params string[] outParameters)
        {
            try
            {
                return _dal.ExecuteNonQuery(query, search, outParameters);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public T GetByID<T>(object entityID)
        {
            try
            {
                return _dal.GetByID<T>(entityID);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public T GetEntity<T>(SearchCriteria search)
        {
            try
            {
                return _dal.GetEntity<T>(search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public T GetEntity<T>(string query, SearchCriteria search)
        {
            try
            {
                return _dal.GetEntity<T>(query, search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public DataTable GetDataTable<T>(SearchCriteria search)
        {
            try
            {
                return _dal.GetDataTable<T>(search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }

        public DataTable GetDataTable(string query, SearchCriteria search)
        {
            try
            {
                return _dal.GetDataTable(query, search);
            }
            catch (DataAccessException ex)
            {
                throw new BusinessLogicException(ex.Message);
            }
        }
    }
}
